/**
 * 防抖
 * 在指定时间段内多次频繁提交只触发最后一次
 * @example vue中使用说明
 * {
 *    data() {
 *      return {
 *        value: ''
 *      }
 *    },
 *    created(){
 *      this.$watch('value', debounce((newVal,oldVal)=>{ //执行异步逻辑 }))
 *    }
 * }
 */
 export function debounce (fn, timeout = 300) {
  let stop = null
  return function (...args) {
    if (stop) {
      clearTimeout(stop)
    }

    stop = setTimeout(() => {
      fn(...args)
    }, timeout)
  }
}

function type (data) {
  if (data === null || data === undefined) {
    return null
  }

  const proto = Object.getPrototypeOf(data)

  if (proto) {
    return proto.constructor.name.toLowerCase()
  } else {
    return typeof proto
  }
}

/**
 * 深度克隆
 * @param {*} data
 */
export function deepClone (data) {
  var t = type(data); var o; var i; var ni

  if (t === 'array') {
    o = []
  } else if (t && t === 'object') {
    o = {}
  } else {
    return data
  }

  if (t === 'array') {
    for (i = 0, ni = data.length; i < ni; i++) {
      o.push(deepClone(data[i]))
    }
    return o
  } else if (t === 'object') {
    for (i in data) {
      o[i] = deepClone(data[i])
    }
    return o
  }
}

/**
 * 字符串数组格式转数组
 * 如：
 * a,b,c
 * [a,b,c]
 * @param {String} val
 * @param {Function} convert
 */
 export function strToArr (val, defaultValue = val) {
  if (!val) {
    return []
  } else if (val instanceof Array) {
    return defaultValue
  } else {
    try {
      return JSON.parse(val)
    } catch (e) {
      console.error('convert array error', val)
      console.error(e)

      return []
    }
  }
}

/**
 * 转成json对象
 * @param {*} val
 * @param {*} defaultValue
 */
export function strToJson (val, defaultValue = {}) {
  try {
    if (!val) {
      return defaultValue
    } else if (typeof val === 'object') {
      return val
    } else {
      return JSON.parse(val)
    }
  } catch (e) {
    console.error(e)

    return val
  }
}

/**
 * 字符串转数字
 * @param {String|Number} val
 */
export function strToNum (val) {
  if (typeof val === 'number') {
    return val
  } else if (!val && val !== 0) {
    return 0
  }

  return parseFloat(val)
}

/**
 * 字符串转整数
 * @param {String|Number} val
 */
export function strToInt (val) {
  if (typeof val === 'number') {
    return val
  }

  return val >> 0
}

/**
 * 字符串转bool
 * @param {String} val
 */
export function strToBool (val) {
  if (typeof val === 'string') {
    if (val === 'true') {
      return true
    } else {
      return false
    }
  } else {
    return !!val
  }
}

const commonConverter = {
  boolean: strToBool,
  integer: strToNum,
  object: strToJson,
  number: strToNum,
  array: strToArr,
  int: strToNum
}

const Converter = {
  from: {
    ...commonConverter,
    arrayString (value) {
      if (value && typeof value === 'string') {
        return value.split(',')
      } else if (value instanceof Array) {
        return value
      } else {
        return []
      }
    }
  },
  to: commonConverter
}

export function setValueToConfig (config, value) {
  value = value !== undefined ? value : config.value

  const { type } = config

  if (Converter.to[type]) {
    return Converter.to[type](value)
  }

  return value
}

/**
 * 转换成可编辑的格式
 * @param {*} config
 * @param {*} value
 */
export function getValueFromConfig (config, value) {
  value = value !== undefined ? value : config.value

  const { type } = config

  if (Converter.from[type]) {
    return Converter.from[type](value)
  }

  return value
}
